package persistence.dao.mysql;

import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 * Interface DAO implémenté selon le choix de l'utilisateur
 * @author Wadjahdi Marc
 */
public class MySQLDAO<T> {

    protected EntityManager em = null;
    protected EntityTransaction tx = null;
    protected Class<?> classe = null;

    public MySQLDAO(EntityManager em, Class<?> classe) {
        this.classe = classe;
        this.em = em;
        tx = em.getTransaction();
    }

    /**
     *  Méthode pour insérer un objet dans la base de données
     * @param object objet inséré dans la base de données
     * @return renvoie true si l'insertion s'est bien passée ou false sinon
     */
    public boolean insert(T object) {
        try {
            tx.begin();

            em.persist(object);

            tx.commit();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null) {
                tx.rollback();
                return false;
            }
        }
        return false;
    }

    /**
     * Méthode pour supprimer un objet de la base de données
     * @param object objet à retirer de la base de données
     * @return retourne true si la suppression s'set bien passée ou false sinon
     */
    public boolean delete(T object) {
        try {
            tx.begin();

            em.remove(object);

            tx.commit();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null) {
                tx.rollback();
                return false;
            }
        }
        return false;
    }

    /**
     * Méthode qui recherche un objet à l'aide de son Id dans la base de données
     * @param id id de l'objet à trouver
     * @return renvoie l'objet trouvé ou null si aucun objet ne correspond dans la base de données
     */
    public T findById(int id) {
        String className = classe.getSimpleName();
        String textQuery = "select o from " + className + " as o where o.id = :objectid";
        Query query = em.createQuery(textQuery);
        query.setParameter("objectid", id);
        try {
            return (T) query.getSingleResult();
        } catch (NoResultException e) {
            return null;
        }
    }

    /**
     * Methode qui recherche tous les objets du même type
     * @return Renvoie la liste des objets du même type
     */
    public List<T> findAll() {
        String className = classe.getSimpleName();

        String textQuery = "select o from " + className + " as o";
        Query query = em.createQuery(textQuery);

        List list = query.getResultList();

        return list;
    }

    /**
     * Méthode qui met à jour un objet tel qu'il est actuellement dans la base de données
     * @param object objet à mettre à jour
     * @return
     */
    public boolean update(Object object) {
        try {
            tx.begin();

            em.persist(object);

            tx.commit();

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            if (tx != null) {
                tx.rollback();
                return false;
            }
        }
        return false;
    }
}
